import CryptoJS from 'crypto-js';
import LZString from 'lz-string';

// 初始化密钥和向量
const key = CryptoJS.enc.Utf8.parse('12345678901234567890123456789012');
const iv = CryptoJS.enc.Utf8.parse('1234567890123456');

/**
 * 加密密码
 * @param {string} password - 要加密的密码
 * @returns {string} - 加密后的字符串
 */
export const encryptPassword = (password) => {
  return CryptoJS.AES.encrypt(password, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  }).toString();
};

/**
 * 通用加密函数，与主项目保持一致
 * @param {string} text - 要加密的文本
 * @returns {string} - 加密后的字符串
 */
export const encrypt = (text) => {
  // 使用相同的加密方式，确保与主项目兼容
  return CryptoJS.AES.encrypt(text, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  }).toString();
};

/**
 * 解密函数
 * @param {string} encryptedText - 加密的文本
 * @returns {string} - 解密后的文本
 */
export const decrypt = (encryptedText) => {
  try {
    const bytes = CryptoJS.AES.decrypt(encryptedText, key, {
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    });
    return bytes.toString(CryptoJS.enc.Utf8);
  } catch (error) {
    console.error('解密失败:', error);
    return '';
  }
};

// 企业级短链接编码字符集 - 使用URL安全的字符，避免特殊字符
const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';

/**
 * 将数字转换为短码
 * @param {number} num - 要转换的数字
 * @returns {string} - 生成的短码
 */
const numToShortCode = (num) => {
  let code = '';
  while (num > 0) {
    code = CHARS[num % CHARS.length] + code;
    num = Math.floor(num / CHARS.length);
  }
  return code || CHARS[0]; // 确保至少返回一个字符
};

/**
 * 将字符串转换为数字哈希
 * @param {string} str - 要哈希的字符串
 * @returns {number} - 生成的哈希数字
 */
const stringToHash = (str) => {
  let hash = 0;
  if (str.length === 0) return hash;
  
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash = hash & hash; // 转换为32位整数
  }
  
  return Math.abs(hash);
};

/**
 * 企业级URL加密为超短链接
 * @param {string} url - 原始URL或数据
 * @returns {string} - 加密后的短链接参数
 */
export const encryptUrlCompact = (url) => {
  if (!url) return '';
  
  try {
    // 1. 先压缩数据 - 使用LZMA算法压缩
    const compressed = CryptoJS.enc.Utf8.parse(url);
    
    // 2. 计算哈希值
    const hash = stringToHash(url);
    
    // 3. 生成短码
    const shortCode = numToShortCode(hash);
    
    // 4. 加密哈希和原始数据的组合，作为备份验证
    const timestamp = Date.now().toString(36);
    const hashPart = shortCode.substring(0, 6); // 取前6位作为短码
    
    // 5. 将哈希和时间戳组合，确保唯一性
    return hashPart + timestamp.substring(0, 3);
  } catch (error) {
    console.error('URL短链接生成失败:', error);
    return '';
  }
};

// Base62编码字符集（数字+大小写字母）
const BASE62_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

/**
 * 将数字转换为Base62字符串
 * @param {number} num - 要转换的数字
 * @returns {string} - Base62编码的字符串
 */
const toBase62 = (num) => {
  if (num === 0) return BASE62_CHARS[0];
  
  let result = '';
  while (num > 0) {
    result = BASE62_CHARS[num % 62] + result;
    num = Math.floor(num / 62);
  }
  
  return result;
};

/**
 * 将Base62字符串转换为数字
 * @param {string} str - Base62编码的字符串
 * @returns {number} - 解码后的数字
 */
const fromBase62 = (str) => {
  let result = 0;
  for (let i = 0; i < str.length; i++) {
    const char = str[i];
    const value = BASE62_CHARS.indexOf(char);
    if (value === -1) throw new Error('无效的Base62字符: ' + char);
    result = result * 62 + value;
  }
  return result;
};

/**
 * 生成文件预览超短链接 - 高效压缩方案
 * @param {Object} fileInfo - 文件信息对象 {url, name, type}
 * @returns {string} - 生成的短链接参数
 */
export const generateCompactLink = (fileInfo) => {
  if (!fileInfo || !fileInfo.url) return '';
  
  try {
    // 1. 将文件信息对象转为JSON字符串
    const infoStr = JSON.stringify(fileInfo);
    
    // 2. 使用LZString进行高效压缩，直接输出URL安全的字符串
    return LZString.compressToEncodedURIComponent(infoStr);
  } catch (error) {
    console.error('生成短链接失败:', error);
    return '';
  }
};

/**
 * 解析文件预览短链接
 * @param {string} shortCode - 短链接参数
 * @returns {Object|null} - 解析出的文件信息对象 {url, name, type}
 */
export const parseCompactLink = (shortCode) => {
  if (!shortCode) return null;
  
  try {
    // 使用LZString解压缩
    const decompressed = LZString.decompressFromEncodedURIComponent(shortCode);
    
    if (!decompressed) {
      console.error('短链接解压失败，数据可能已损坏');
      return null;
    }
    
    // 解析JSON字符串为对象
    return JSON.parse(decompressed);
  } catch (error) {
    console.error('解析短链接失败:', error);
    return null;
  }
};

/**
 * URL加密为短链接格式
 * @param {string} url - 原始URL
 * @returns {string} - 加密后的短链接参数
 */
export const encryptUrl = (url) => {
  if (!url) return '';
  
  try {
    // 1. 先使用AES加密
    const encrypted = encrypt(url);
    
    // 2. 转为Base64编码
    const base64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(encrypted));
    
    // 3. 替换URL不安全字符
    return base64
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=/g, '');
  } catch (error) {
    console.error('URL加密失败:', error);
    return '';
  }
};

/**
 * 解密短链接参数为原始URL
 * @param {string} shortCode - 短链接参数
 * @returns {string} - 解密后的原始URL
 */
export const decryptUrl = (shortCode) => {
  if (!shortCode) return '';
  
  try {
    // 1. 还原URL安全Base64
    let base64 = shortCode
      .replace(/-/g, '+')
      .replace(/_/g, '/');
    
    // 添加可能缺失的填充字符
    while (base64.length % 4) {
      base64 += '=';
    }
    
    // 2. Base64解码
    const decoded = CryptoJS.enc.Base64.parse(base64).toString(CryptoJS.enc.Utf8);
    
    // 3. AES解密
    return decrypt(decoded);
  } catch (error) {
    console.error('短链接解密失败:', error);
    return '';
  }
};

/**
 * 生成文件预览短链接
 * @param {Object} fileInfo - 文件信息对象 {url, name, type}
 * @returns {string} - 生成的短链接参数
 */
export const generateShortLink = (fileInfo) => {
  if (!fileInfo || !fileInfo.url) return '';
  
  try {
    // 将文件信息对象转为JSON字符串
    const infoStr = JSON.stringify(fileInfo);
    
    // 加密为短链接参数
    return encryptUrl(infoStr);
  } catch (error) {
    console.error('生成短链接失败:', error);
    return '';
  }
};

/**
 * 解析文件预览短链接
 * @param {string} shortCode - 短链接参数
 * @returns {Object|null} - 解析出的文件信息对象 {url, name, type}
 */
export const parseShortLink = (shortCode) => {
  if (!shortCode) return null;
  
  try {
    // 解密短链接参数
    const decrypted = decryptUrl(shortCode);
    if (!decrypted) return null;
    
    // 解析JSON字符串为对象
    return JSON.parse(decrypted);
  } catch (error) {
    console.error('解析短链接失败:', error);
    return null;
  }
};

/**
 * 验证访客密码
 * @param {string} password - 输入的密码
 * @returns {boolean} - 是否验证通过
 */
export const validatePassword = (password) => {
  // 硬编码的访客密码，仅用于预览功能
  return password === '0282' || encryptPassword(password) === 'Fsj/afJAaqLna5Jkxpj7jg==';
};

/**
 * 验证管理员密码
 * @param {string} password - 输入的密码
 * @param {string} encryptedPassword - 加密后的密码
 * @returns {boolean} - 是否验证通过
 */
export const validateAdminPassword = (password, encryptedPassword) => {
  // 管理员密码需要与数据库中的加密密码比对
  return encrypt(password) === encryptedPassword;
};

/**
 * 禁止复制功能
 */
export const forbidCopy = () => {
  // 检查权限设置
  const checkPermission = () => {
    try {
      // 动态导入权限store
      const permissionStore = window.$pinia?.state?.value?.permission;
      
      // 如果权限store存在且允许复制粘贴，则不应用复制限制
      if (permissionStore && permissionStore.pageInteraction.copyPaste.enabled) {
        console.log('权限设置允许复制粘贴，不应用复制限制');
        return false;
      }
    } catch (e) {
      console.error('检查复制粘贴权限时出错:', e);
    }
    
    // 默认应用复制限制
    return true;
  };
  
  // 如果权限设置允许复制粘贴，则不应用限制
  if (!checkPermission()) {
    return;
  }
  
  // 1. 禁止文本选择
  document.addEventListener('mousedown', e => e.preventDefault());
  document.addEventListener('selectstart', e => e.preventDefault());
  document.addEventListener('contextmenu', e => e.preventDefault());
  document.addEventListener('keydown', e => {
    if ((e.ctrlKey || e.metaKey) && ['c','x','v'].includes(e.key)) e.preventDefault();
  });
  document.querySelectorAll('img').forEach(img => {
    img.addEventListener('dragstart', e => e.preventDefault());
  });

  // 2. 禁止iframe内容复制
  const applyIframeProtection = () => {
    document.querySelectorAll('iframe').forEach(iframe => {
      try {
        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
        
        // 给iframe内部添加禁止复制事件
        iframeDoc.addEventListener('mousedown', e => e.preventDefault());
        iframeDoc.addEventListener('selectstart', e => e.preventDefault());
        iframeDoc.addEventListener('contextmenu', e => e.preventDefault());
        iframeDoc.addEventListener('keydown', e => {
          if ((e.ctrlKey || e.metaKey) && ['c','x','v'].includes(e.key)) e.preventDefault();
        });
        
        // 添加CSS禁止选择
        const style = iframeDoc.createElement('style');
        style.textContent = `
          * {
            -webkit-user-select: none !important;
            -moz-user-select: none !important;
            -ms-user-select: none !important;
            user-select: none !important;
          }
        `;
        iframeDoc.head.appendChild(style);
        
        // 禁止iframe内图片拖拽
        iframeDoc.querySelectorAll('img').forEach(img => {
          img.addEventListener('dragstart', e => e.preventDefault());
        });
      } catch (e) {
        console.log('无法访问iframe内容，可能是跨域限制');
      }
    });
  };

  // 初始应用保护
  applyIframeProtection();
  
  // 监听iframe加载事件
  const observeIframes = () => {
    const observer = new MutationObserver(mutations => {
      mutations.forEach(mutation => {
        if (mutation.addedNodes) {
          mutation.addedNodes.forEach(node => {
            if (node.tagName === 'IFRAME') {
              // 等待iframe加载完成
              node.addEventListener('load', () => applyIframeProtection());
            }
            // 检查子节点中是否有iframe
            if (node.querySelectorAll) {
              node.querySelectorAll('iframe').forEach(iframe => {
                iframe.addEventListener('load', () => applyIframeProtection());
              });
            }
          });
        }
      });
    });
    
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  };
  
  observeIframes();

  // 3. 添加全局CSS禁止选择
  const style = document.createElement('style');
  style.textContent = `
    * {
      -webkit-user-select: none !important;
      -moz-user-select: none !important;
      -ms-user-select: none !important;
      user-select: none !important;
    }
  `;
  document.head.appendChild(style);

  // 4. 防止开发者工具打开（简易的检测）
  (function() {
    var devtools = /./;
    devtools.toString = function() {};
    console.log('%c', devtools); 
  })();

  // 5. 检测页面是否被切换到后台（增加防止截图的难度）
  document.addEventListener('visibilitychange', function() {
    if (document.hidden) {
      console.log("页面已被隐藏，可能正在进行截图/录屏");
    }
  });
};

export default {
  encryptPassword,
  encrypt,
  decrypt,
  encryptUrl,
  decryptUrl,
  encryptUrlCompact,
  generateShortLink,
  parseShortLink,
  generateCompactLink,
  parseCompactLink,
  validatePassword,
  validateAdminPassword,
  forbidCopy
}; 